package com.atguigu.srb.sms.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.srb.exception.SRBException;
import com.atguigu.srb.result.ResponseEnum;
import com.atguigu.srb.result.ResponseVo;
import com.atguigu.srb.sms.feignClient.CoreFeignClient;
import com.atguigu.srb.sms.properties.SMSProperties;
import com.atguigu.srb.sms.service.SMSService;
import com.atguigu.srb.util.HttpUtils;
import com.atguigu.srb.util.RandomUtils;
import com.atguigu.srb.util.RegexValidateUtils;
import com.atguigu.srb.util.SrbAssert;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * ClassName: SMSServiceImpl
 * Package: com.atguigu.srb.sms.service.impl
 * Description:
 *
 * @Author 刘强
 * @Create 2024/4/18 21:20
 * @Version 1.0
 */
@Service
@EnableConfigurationProperties(SMSProperties.class) //开启属性绑定 --> 制定属性类
public class SMSServiceImpl implements SMSService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private CoreFeignClient coreFeignClient;

    @Override
    public void sendSMS(String mobile, Integer type) {
        SrbAssert.assertTrue(type == 1);
        String sendCountLimitDayKey = "sms:count:" + type + ":" + mobile;
        String sendOneTimeLimitKey = "sms:code:" + type + ":" + mobile;
        // 1. 校验手机号的格式
        SrbAssert.assertTrue(RegexValidateUtils.checkCellphone(mobile), ResponseEnum.MOBILE_ERROR);
        // 1.1  校验手机号是否已经被使用
        // 发送请求给core服务  --> 通过openFeign来实现远程访问
        ResponseVo responseVo = coreFeignClient.isMobileUsed(mobile);
        if(responseVo.getCode() == -1){
            throw new SRBException(responseVo.getMessage(),-1);
        }
//        System.out.println("responseVo = " + responseVo);
        Boolean isMobileUsed = (Boolean) responseVo.getData().get("isMobileUsed");
        SrbAssert.assertNotNull(isMobileUsed,ResponseEnum.ERROR);
        SrbAssert.assertNotTrue(isMobileUsed,ResponseEnum.MOBILE_EXIST_ERROR);
        // 2. 限制发送次数  5分钟一次  一天最多5次  --> redis缓存
        //  5分钟一次
        SrbAssert.assertNotTrue(stringRedisTemplate.hasKey(sendOneTimeLimitKey), ResponseEnum.ALIYUN_SMS_LIMIT_CONTROL_ERROR);
//        String sendOneTimeLimit = stringRedisTemplate.opsForValue().get(sendOneTimeLimitKey);
//        if (!("".equals(sendOneTimeLimit) || sendOneTimeLimit == null)) {
//            throw new SRBException(ResponseEnum.ALIYUN_SMS_LIMIT_CONTROL_ERROR);
//        }
        // 一天最多5次
        Boolean hasKey = stringRedisTemplate.hasKey(sendCountLimitDayKey);
        if (hasKey) {
            Integer sendCountLimitDay = Integer.parseInt(stringRedisTemplate.opsForValue().get(sendCountLimitDayKey));
            SrbAssert.assertNotTrue(sendCountLimitDay >= 5,ResponseEnum.ALIYUN_SMS_ERROR);
        } else {
            stringRedisTemplate.opsForValue().set(sendCountLimitDayKey, "0", 24, TimeUnit.HOURS);
        }

        // 3. 生成验证码，发送短信
        String verifyCode = RandomUtils.getSixBitRandom();

//        sendMsg(mobile, verifyCode);
        // 4. 缓存验证码 和 更新每天发送次数
        stringRedisTemplate.opsForValue().set(sendOneTimeLimitKey, verifyCode, 5, TimeUnit.MINUTES);
        stringRedisTemplate.opsForValue().increment(sendCountLimitDayKey);

    }

    public void sendMsg(String mobile, String verifyCode) {
        try {
            String host = SMSProperties.HOST;
            String path = SMSProperties.PATH;
            String method = SMSProperties.METHOD;
            String appcode = SMSProperties.APPCODE;
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("Authorization", "APPCODE " + appcode);
            Map<String, String> querys = new HashMap<String, String>();
            querys.put("mobile", mobile);
            querys.put("content", "【智能云】您的验证码是" + verifyCode + "。如非本人操作，请忽略本短信");

            HttpResponse response = HttpUtils.doGet(host, path, method, headers, querys);
            //获取response的body
            String responseResult = EntityUtils.toString(response.getEntity());
            System.out.println("responseResult = " + responseResult);
            Map responseResultMap = JSON.parseObject(responseResult, Map.class);
            String code = responseResultMap.get("error_code").toString();
            String message = responseResultMap.get("reason").toString();
            if (!"0".equals(code)) {
                throw new SRBException(ResponseEnum.ALIYUN_SMS_ERROR);
            }
        } catch (SRBException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
}
